#include "bsp_usart.h"
#include <stdarg.h>

// struct uart_dev uart0 = {
//     .reg_addr = USART0,
//     .rx_buf = {0},
//     .rx_cnt = 0,
//     .init = bsp_usart0_init,
//     .tx = uart0_tx,
// };

/* uart0-->RS485 */
void bsp_usart0_init(uint32_t bps)
{	
	/* enable USART clock */
    rcu_periph_clock_enable(RCU_USART0);

    /* connect port to USARTx_Tx */
    gpio_init(RS485_TX_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, RS485_TX_PIN);
    /* connect port to USARTx_Rx */
    gpio_init(RS485_RX_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, RS485_RX_PIN);

    /* USART configure */
    usart_deinit(USART0);
    usart_baudrate_set(USART0, bps);
	usart_stop_bit_set(USART0, 1);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);
	
    /* USART interrupt configuration */
    nvic_irq_enable(USART0_IRQn, 2, 2);
	
    /* enable USART RBNE interrupt */  
    usart_interrupt_enable(USART0, USART_INT_RBNE);
	
	/* rs485 default recv mode */
	rs485_mode_set(TX);
}

/*****************  发送一个字节 **********************/
void usart_sendbyte(uint32_t usart_periph, uint8_t ch)
{
	/* 发送一个字节数据到USART */
	usart_data_transmit(usart_periph, ch);	
	
	/* 等待发送数据寄存器为空 */
	while (usart_flag_get(usart_periph, USART_FLAG_TBE) == RESET);
}

/* 串口0发送 */
void uart0_tx(uint8_t *str,uint16_t strlen )
{
	unsigned int k=0;

	rs485_mode_set(TX);	//切换为发送
    do 
    {
        usart_sendbyte(USART0, *(str + k));
        k++;
    } while(k < strlen);
		
	/* 加短暂延时，保证485发送数据完毕 */
	while (usart_flag_get(USART0, USART_FLAG_TC) == RESET);  /* 有用 */
		
	rs485_mode_set(RX);	//切换为接收模式
}

/* _485延时等待，切换收发模式时等待硬件完成 */
void rs485_delay()
{
	__IO uint32_t count = 300;
	for(;count!=0;count--);
}

/* 控制485模块收发模式 0:recv, 1:send*/
void rs485_mode_set(enum rs485_mode mode)
{
	rs485_delay();
	gpio_bit_write(RS485_MODE_PORT, RS485_MODE_PIN, (bit_status)mode);
	rs485_delay();
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
	usart_data_transmit(USART0, (uint8_t)ch);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    return ch;
}


/* usart0_irqhandler */
void USART0_IRQHandler(void)
{
    if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){
		uart0_rx_buf[uart0_rx_cnt++] = usart_data_receive(USART0);  /* 接收数据，自动清中断 */
		uart0_frame_end_flag = RECEIVING;
    }
}

